package com.xzq.erp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xzq.erp.constants.UserPasswordConstants;
import com.xzq.erp.context.BaseContext;
import com.xzq.erp.domain.dto.PageDTO;
import com.xzq.erp.domain.dto.UserDTO;
import com.xzq.erp.domain.po.SysUser;
import com.xzq.erp.domain.po.SysUserRole;
import com.xzq.erp.domain.query.UserPageQuery;
import com.xzq.erp.domain.vo.UserRoleVO;
import com.xzq.erp.domain.vo.UserVO;
import com.xzq.erp.enums.ResponseCodeEnum;
import com.xzq.erp.exception.BizException;
import com.xzq.erp.mapper.SysUserMapper;
import com.xzq.erp.service.ISysUserRoleService;
import com.xzq.erp.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author xzq
 * @since 2025-05-19
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private final ISysUserRoleService sysUserRoleService;

    private final PasswordEncoder passwordEncoder;

    @Override
    public PageDTO<UserVO> getUserList(UserPageQuery query) {
        Long userId = BaseContext.getUserId();
        PageHelper.startPage(query.getCurrent(), query.getSize());
        List<SysUser> list = lambdaQuery()
                .like(StrUtil.isNotBlank(query.getUserName()), SysUser::getUsername, query.getUserName())
                .like(StrUtil.isNotBlank(query.getNickName()), SysUser::getNickname, query.getNickName())
                .eq(Objects.nonNull(query.getStatus()), SysUser::getStatus, query.getStatus())
                .notIn(SysUser::getId,userId)
                .orderByAsc(SysUser::getCreateTime)
                .list();
        PageInfo<SysUser> page = new PageInfo<>(list);
        log.info("查询结果:{},{}", page.getPages(), page.getTotal());
        List<SysUser> records = page.getList();
        if(CollectionUtils.isEmpty(records)){
            return PageDTO.empty(page.getTotal(), (long)page.getPages());
        }
        List<Integer> userIds = records.stream().map(SysUser::getId).collect(Collectors.toList());
        // 查询用户角色
        List<UserRoleVO> userRoleVOList = sysUserRoleService.getUserRoleVOList(userIds);
        Map<Integer, List<UserRoleVO>> map = userRoleVOList.stream().collect(Collectors.groupingBy(UserRoleVO::getUserId));
        List<UserVO> vos = Lists.newArrayList();
        for(SysUser user : records){
            UserVO vo = BeanUtil.toBean(user, UserVO.class);
            vo.setUserRoleList(map.getOrDefault(user.getId(),  Lists.newArrayList()));
            vos.add(vo);
        }
        return PageDTO.of(new Page<>(query.getCurrent(),query.getSize(),page.getTotal()), vos);
    }

    @Override
    @Transactional
    public void addUser(UserDTO userDTO) {
        if(StrUtil.isBlank(userDTO.getPassword())){
            throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID);
        }
        try{
            SysUser user = BeanUtil.toBean(userDTO, SysUser.class);
            String password = passwordEncoder.encode(userDTO.getPassword());
            user.setPassword(password);
            save(user);
            // 保存用户角色关联
            sysUserRoleService.saveBatch(userDTO.getRoleIds().stream().map(roleId -> {
                SysUserRole userRoleVO = new SysUserRole();
                userRoleVO.setUserId(user.getId());
                userRoleVO.setRoleId(roleId);
                return userRoleVO;
            }).collect(Collectors.toList()));
            log.info("保存用户成功:{}", user);
        }
        catch (Exception e){
            throw new BizException(ResponseCodeEnum.USERNAME_ALREADY_EXISTS);
        }
    }

    @Override
    @Transactional
    public void updateUser(UserDTO userDTO) {
        if(Objects.isNull(userDTO.getId())){
            userDTO.setId(BaseContext.getUserId().intValue());
        }
        else{
            if(StrUtil.isBlank(userDTO.getUsername()) || StrUtil.isBlank(userDTO.getNickname()) || Objects.isNull(userDTO.getStatus())){
                throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID);
            }
        }
        if(Objects.isNull(userDTO.getId())){
            throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID);
        }
        SysUser user = BeanUtil.toBean(userDTO, SysUser.class);
        updateById(user);
        log.info("更新用户成功:{}", user);
        if(userDTO.getId().equals(BaseContext.getUserId().intValue())){
            return;
        }
        // 删除用户角色关联
        sysUserRoleService.remove(
                new LambdaQueryWrapper<SysUserRole>()
                        .eq(SysUserRole::getUserId, userDTO.getId())
        );
        // 保存用户角色关联
        sysUserRoleService.saveBatch(userDTO.getRoleIds().stream().map(roleId -> {
            SysUserRole userRoleVO = new SysUserRole();
            userRoleVO.setUserId(user.getId());
            userRoleVO.setRoleId(roleId);
            return userRoleVO;
        }).collect(Collectors.toList()));
    }

    @Override
    public void resetPassword(Long id) {
        SysUser user = new SysUser();
        user.setId(id.intValue());
        user.setPassword(passwordEncoder.encode(UserPasswordConstants.DEFAULT_PASSWORD));
        this.updateById(user);
    }

    @Override
    @Transactional
    public void deleteUser(Long id) {
        removeById(id);
        sysUserRoleService.removeByUserId(id);
    }

    @Override
    public UserVO getUserInfo() {
        Long userId = BaseContext.getUserId();
        SysUser user = getById(userId);
        UserVO vo = BeanUtil.toBean(user, UserVO.class);
        List<UserRoleVO> userRoleVOList = sysUserRoleService.getUserRoleVOList(Collections.singletonList(user.getId()));
        vo.setUserRoleList(userRoleVOList);
        return vo;
    }

    @Override
    public void updatePassword(UserDTO userDTO) {
        if(Objects.isNull(userDTO.getPassword()) || Objects.isNull(userDTO.getNewPassword())){
            throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID);
        }
        // 获取当前登录用户id
        Long userId = BaseContext.getUserId();
        SysUser user = getById(userId);
        if(!passwordEncoder.matches(userDTO.getPassword(), user.getPassword())){
            throw new BizException(ResponseCodeEnum.USER_PASSWORD_ERROR);
        }
        user.setPassword(passwordEncoder.encode(userDTO.getNewPassword()));
        updateById(user);
    }
}
